home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / sys5_io.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  8KB  |  452 lines

  1. /* OS- and machine-dependent stuff for SYS5 */
  2.  
  3. /*
  4.     FILE: UNIX.io.c
  5.     
  6.     Routines:
  7.         ioinit()
  8.         iostop()
  9.         asy_init()
  10.         asy_stop()
  11.         asy_speed()
  12.         asy_output()
  13.         asy_recv()
  14.         dir()
  15.     Written or converted by Mikel Matthews, N9DVG
  16.     SYS5 added by Jere Sandidge, K4FUM
  17.     Directory pipe added by Ed DeHart, WA3YOA
  18.     Numerous changes by Charles Hedrick and John Limpert, N3DMC
  19.     Hell, *I* even hacked on it... :-)  Bdale, N3EUA
  20.     
  21.     If you want to use the select code, define SELECT in the makefile or
  22.     in this file.
  23. */
  24.  
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <termio.h>
  28. #include <signal.h>
  29. #include <sys/file.h>
  30. #include <sys/dir.h>
  31. #include <time.h>
  32. #include <fcntl.h>
  33. #include <memory.h>
  34. #include <string.h>
  35. #include "global.h"
  36. #include "asy.h"
  37. #include "mbuf.h"
  38. #include "internet.h"
  39. #include "iface.h"
  40. #include "unix.h"
  41. #include "cmdparse.h"
  42.  
  43. #ifndef    B19200
  44. #define    B19200    EXTA
  45. #endif
  46.  
  47. #ifndef    B38400
  48. #define    B38400    EXTB
  49. #endif
  50.  
  51. struct asy asy[ASY_MAX];
  52. struct interface *ifaces;
  53. struct termio mysavetty, savecon;
  54. int savettyfl;
  55. int    IORser[ASY_MAX];
  56.  
  57.  
  58. /* Called at startup time to set up console I/O, memory heap */
  59. ioinit()
  60. {
  61.     struct termio ttybuf;
  62.     extern void ioexit();
  63.  
  64.     (void) signal(SIGHUP, ioexit);
  65.     (void) signal(SIGINT, ioexit);
  66.     (void) signal(SIGQUIT, ioexit);
  67.     (void) signal(SIGTERM, ioexit);
  68.  
  69.     ioctl(0, TCGETA, &ttybuf);
  70.     savecon = ttybuf;
  71.  
  72.     ttybuf.c_iflag &= ~IXON;
  73.     ttybuf.c_lflag &= ~(ICANON|ISIG|ECHO);
  74.     ttybuf.c_cc[VTIME] = '\01';
  75.     ttybuf.c_cc[VMIN] = '\0';
  76.     if ((savettyfl = fcntl(0, F_GETFL, 0)) == -1) {
  77.         perror("Could not read console flags");
  78.         return -1;
  79.     }
  80. #ifdef    notdef
  81.     fcntl(0, F_SETFL, savettyfl | O_NDELAY);
  82. #endif
  83.  
  84.     ioctl(0, TCSETAW, &ttybuf);
  85.     return 0;
  86. }
  87.  
  88.  
  89. /* Called just before exiting to restore console state */
  90. void
  91. iostop()
  92. {
  93.     setbuf(stdout,NULLCHAR);
  94.  
  95.     while (ifaces != NULLIF) {
  96.         if (ifaces->stop != NULLFP)
  97.             (*ifaces->stop)(ifaces->dev);
  98.         ifaces = ifaces->next;
  99.     }
  100.  
  101.     ioctl(0, TCSETAW, &savecon);
  102.     fcntl(0, F_SETFL, savettyfl);
  103. }
  104.  
  105. void
  106. ioexit()
  107. {
  108.     iostop();
  109.     exit(0);
  110. }
  111.  
  112. /* Initialize asynch port "dev" */
  113. /*ARGSUSED*/
  114. int
  115. asy_init(dev, arg1, arg2, bufsize)
  116. int16 dev;
  117. char *arg1, *arg2;
  118. unsigned bufsize;
  119. {
  120.     register struct asy *ap;
  121.     struct termio    sgttyb;
  122.  
  123. #ifdef    SYS5_DEBUG
  124.     printf("asy_init: called\n");
  125. #endif    /* SYS5_DEBUG */
  126.  
  127.     if (dev >= nasy)
  128.         return -1;
  129.  
  130.     ap = &asy[dev];
  131.     ap->tty = malloc((unsigned)(strlen(arg2)+1));
  132.     strcpy(ap->tty, arg2);
  133.     printf("asy_init: tty name = %s\n", ap->tty);
  134.  
  135.     if ((IORser[dev] = open(ap->tty, (O_RDWR|O_NDELAY), 0)) < 0) {
  136.         perror("Could not open device IORser");
  137.         return -1;
  138.     }
  139.  
  140.  /* 
  141.   * get the stty structure and save it 
  142.   */
  143.  
  144.     if (ioctl(IORser[dev], TCGETA, &mysavetty) < 0)    {
  145.         perror("ioctl failed on device");
  146.         return -1;
  147.     }
  148.  
  149.  /* 
  150.   * copy over the structure 
  151.   */
  152.  
  153.     sgttyb = mysavetty;
  154.     sgttyb.c_iflag = (IGNBRK | IGNPAR);
  155.     sgttyb.c_oflag = 0;
  156.     sgttyb.c_lflag = 0;
  157.     sgttyb.c_cflag = (B9600 | CS8 | CREAD);
  158.     sgttyb.c_cc[VTIME] = 0;
  159.     sgttyb.c_cc[VMIN] = 0;
  160.  
  161.     if (ioctl(IORser[dev], TCSETAF, &sgttyb) < 0) {
  162.         perror("ioctl could not set parameters for IORser");
  163.         return -1;
  164.     }
  165.  
  166.     return 0;
  167. }
  168.  
  169.  
  170. /*ARGSUSED*/
  171. int
  172. asy_stop(iface)
  173. struct interface *iface;
  174. {
  175. }
  176.  
  177.  
  178. /* Set asynch line speed */
  179. int
  180. asy_speed(dev, speed)
  181. int16 dev;
  182. int speed;
  183. {
  184.     struct termio sgttyb;
  185.  
  186.     if (speed == 0 || dev >= nasy)
  187.         return -1;
  188.  
  189. #ifdef    SYS5_DEBUG
  190.     printf("asy_speed: Setting speed for device %d to %d\n",dev, speed);
  191. #endif
  192.  
  193.     asy[dev].speed = speed;
  194.  
  195.     if (ioctl(IORser[dev], TCGETA, &sgttyb) < 0) {
  196.         perror("ioctl could not get parameters");
  197.         return -1;
  198.     }
  199.  
  200.     sgttyb.c_cflag &= ~CBAUD;
  201.  
  202.     switch ((unsigned)speed) {
  203.     case 0:
  204.         sgttyb.c_cflag |= B0;
  205.         break;
  206.     case 50:
  207.         sgttyb.c_cflag |= B50;
  208.         break;
  209.     case 75:
  210.         sgttyb.c_cflag |= B75;
  211.         break;
  212.     case 110:
  213.         sgttyb.c_cflag |= B110;
  214.         break;
  215.     case 134:
  216.         sgttyb.c_cflag |= B134;
  217.         break;
  218.     case 150:
  219.         sgttyb.c_cflag |= B150;
  220.         break;
  221.     case 200:
  222.         sgttyb.c_cflag |= B200;
  223.         break;
  224.     case 300:
  225.         sgttyb.c_cflag |= B300;
  226.         break;
  227.     case 600:
  228.         sgttyb.c_cflag |= B600;
  229.         break;
  230.     case 1200:
  231.         sgttyb.c_cflag |= B1200;
  232.         break;
  233.     case 1800:
  234.         sgttyb.c_cflag |= B1800;
  235.         break;
  236.     case 2400:
  237.         sgttyb.c_cflag |= B2400;
  238.         break;
  239.     case 4800:
  240.         sgttyb.c_cflag |= B4800;
  241.         break;
  242.     case 9600:
  243.         sgttyb.c_cflag |= B9600;
  244.         break;
  245.     case 19200:
  246.         sgttyb.c_cflag |= B19200;
  247.         break;
  248.     case 38400:
  249.         sgttyb.c_cflag |= B38400;
  250.         break;
  251.     default:
  252.         printf("asy_speed: Unknown speed (%d)\n", speed);
  253.         break;
  254.     }
  255.  
  256. #ifdef    SYS5_DEBUG
  257.     printf("speed = %d\n", sgttyb.sg_ispeed);
  258. #endif    /* SYS5_DEBUG */
  259.  
  260.     if (ioctl(IORser[dev], TCSETAW, &sgttyb) < 0) {
  261.         perror("ioctl could not set parameters for IORser");
  262.         return -1;
  263.     }
  264.  
  265.     return 0;
  266. }
  267.  
  268.  
  269. /* Send a buffer to serial transmitter */
  270. asy_output(dev, buf, cnt)
  271. unsigned dev;
  272. char *buf;
  273. unsigned short cnt;
  274. {
  275. #ifdef    SYS5_DEBUG
  276.     printf("asy_output called. dev = %d, cnt = %d\n", dev, cnt);
  277.     printf("buf = %lx\n", (long) buf);
  278.     fflush(stdout);
  279. #endif
  280.     
  281.     if (dev >= nasy)
  282.         return -1;
  283.  
  284.     if (write(IORser[dev], buf, (int)cnt) < cnt) {
  285.         perror("asy_output");
  286.         printf("asy_output: error in writing to device %d\n", dev);
  287.         return -1;
  288.     }
  289.  
  290.     return 0;
  291. }
  292.  
  293. /* Receive characters from asynch line
  294.  * Returns count of characters read
  295.  */
  296. int16
  297. asy_recv(dev,buf,cnt)
  298. int16 dev;
  299. char *buf;
  300. unsigned cnt;
  301. {
  302. #define    IOBUFLEN    256
  303.     unsigned tot;
  304.     int r;
  305.     static struct    {
  306.         char    buf[IOBUFLEN];
  307.         char    *data;
  308.         int    cnt;
  309.     }    IOBUF[ASY_MAX];
  310.  
  311. #ifdef SELECT
  312.     int    mask;
  313.     int    writemask;
  314.     int    ok;
  315.     struct timeval timeout;
  316.     timeout.tv_sec = 0;
  317.     timeout.tv_usec = 35;
  318.     mask = (1<<IORser[dev]);
  319.     writemask = (1<<IORser[dev]);
  320.     ok = 0;
  321.     tot = 0;
  322.     ok = select(mask, &mask, 0, 0, &timeout);
  323.     if ( mask & (1<<IORser[dev]))
  324.     {
  325.         tot = read(IORser[dev], buf, cnt);
  326.     }
  327.     return (tot);
  328. #else
  329.     if(IORser[dev] < 0) {
  330.         printf("asy_recv: bad file descriptor passed for device %d\n",
  331.             dev);
  332.         return(0);
  333.     }
  334.     tot = 0;
  335.     /* fill the read ahead buffer */
  336. #ifdef notdef
  337.     if(IOBUF[dev].cnt == 0 && (rdchk(IORser[dev]) > 0)) {
  338. #else
  339.     if(IOBUF[dev].cnt == 0) {
  340. #endif
  341.         IOBUF[dev].data = IOBUF[dev].buf;
  342.         r = read(IORser[dev], IOBUF[dev].data, IOBUFLEN);
  343.         /* check the read */
  344.         if (r == -1) {
  345.             IOBUF[dev].cnt = 0;    /* bad read */
  346.             perror("asy_recv");
  347.             printf("asy_recv: error in reading from device %d\n", dev);
  348.             return(0);
  349.         } else
  350.             IOBUF[dev].cnt = r;
  351.     } 
  352.     r = 0;    /* return count */
  353.     /* fetch what you need with no system call overhead */
  354.     if(IOBUF[dev].cnt > 0) {
  355.         if(cnt == 1) { /* single byte copy, do it here */
  356.             *buf = *IOBUF[dev].data++;
  357.             IOBUF[dev].cnt--;
  358.             r = 1;
  359.         } else { /* multi-byte copy, left memcpy do the work */
  360.             unsigned n = min(cnt, IOBUF[dev].cnt);
  361.             memcpy(buf, IOBUF[dev].data, n);
  362.             IOBUF[dev].cnt -= n;
  363.             IOBUF[dev].data += n;
  364.             r = n;
  365.         }
  366.     }
  367.     tot = (unsigned int) r;
  368.     return (tot);
  369. #endif
  370. }
  371.  
  372. /* Generate a directory listing by opening a pipe to /bin/ls.
  373.  * If full == 1, give a full listing; else return just a list of names.
  374.  */
  375. FILE *
  376. dir(path,full)
  377. char *path;
  378. int full;
  379. {
  380.     FILE *fp;
  381.     char cmd[1024];
  382.  
  383.     if (path == NULLCHAR || path[0] == '\0')
  384.         path = ".";
  385.  
  386. #ifdef    SYS5_DEBUG
  387.     printf("DIR: path = %s\n", path);
  388. #endif    /* SYS5_DEBUG */
  389.  
  390.     if (full)
  391.         sprintf(cmd,"ls -l %s", path);
  392.     else
  393.         sprintf(cmd, "ls %s", path);
  394.  
  395.     if ((fp = popen(cmd,"r")) == NULLFILE) {
  396.         perror("popen");
  397.         return NULLFILE;
  398.     }
  399.  
  400.     return fp;
  401. }
  402.  
  403.  
  404. asy_ioctl(interface, argc, argv)
  405. struct interface *interface;
  406. int    argc;
  407. char    *argv[];
  408. {
  409.     if (argc < 1) {
  410.         printf("%d\r\n", asy[interface->dev].speed);
  411.         return 0;
  412.     }
  413.  
  414.     return asy_speed(interface->dev, atoi(argv[0]));
  415. }
  416.  
  417. int
  418. OpenPty()
  419. {
  420.     extern int    errno;
  421.     int        pty;
  422.     int        letcnt=0, numcnt=0;
  423.  
  424.     static char    *letters = "pqrs",
  425.             *numbers = "0123456789abcdef";
  426. #ifdef hpux
  427.     static char master[] = "/dev/ptym/ptyXX";
  428. #else
  429.     static char master[] = "/dev/ptyXX";
  430. #endif
  431.     static int    letmax, nummax;
  432.  
  433.     letmax=strlen(letters)-1, nummax=strlen(numbers)-1;
  434.     do {
  435. #ifdef hpux
  436.         master[strlen("/dev/ptym/pty")] = letters[letcnt];
  437.         master[strlen("/dev/ptym/ptyX")] = numbers[numcnt];
  438. #else
  439.         master[strlen("/dev/pty")] = letters[letcnt];
  440.         master[strlen("/dev/ptyX")] = numbers[numcnt];
  441. #endif
  442.         if (letcnt > letmax) {
  443.             return -1;
  444.         } else if (++numcnt > nummax) {
  445.             letcnt++;
  446.             numcnt = 0;
  447.         } 
  448.     } while ((pty=open(master, O_RDWR | O_NDELAY)) < 0);
  449.  
  450.     return(pty);
  451. }
  452.